//
//  GDLog.m
//  GuiderHealth
//
//  Created by zyming on 2022/4/28.
//  Copyright © 2022 YM&EF. All rights reserved.
//

#import "GDLog.h"
#import "NSObject+HZCoding.h"


#define Key_GDLogInfoPath [[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingString:@"GDLogModelInfo.data"]

@implementation GDLog

static BOOL _fileLogOnOrOff;

+ (void)setFileLogOnOrOff:(BOOL)on {
    _fileLogOnOrOff = on;
    [GDLog initHandler];
}
+ (BOOL)getFileLogOnOrOff{
    return _fileLogOnOrOff;
}

+ (void)logWithLine:(NSUInteger)line
             method:(NSString *)methodName
               time:(NSDate *)timeStr
             format:(NSString *)format {
    
    // 日志时间格式化
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday |
    NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond;
    NSDateComponents *comps  = [calendar components:unitFlags fromDate:[NSDate date]];
    NSString *time = [NSString stringWithFormat:@"%ld-%02ld-%02ld %ld:%ld:%ld:%@", (long)comps.year, (long)comps.month, (long)comps.day, (long)comps.hour, (long)comps.minute, (long)comps.second, [[NSString stringWithFormat:@"%ld", (long)comps.nanosecond] substringToIndex:2]];
#if DEBUG
    // debug 直接输出
    fprintf(stderr,"%s %s %tu行: %s.\n", [time UTF8String],[methodName UTF8String],line,[format UTF8String]);
#else
    // release && 文件Log开 写入文件
    if (_fileLogOnOrOff) {
        NSString *logStr = [NSString stringWithFormat:@"[%@]%@ %tu行: ● %@.\n", time, methodName,line,format];
        [self writeLogWithString:logStr time:time];
    }
#endif
}

- (void)addContent:(NSString *)content time:(NSString *)time{

}

+ (void)writeLogWithString:(NSString *)content time:(NSString *)time{
    
    time = [time substringToIndex:10];

    // 名称自定义,上传服务器的时候关联userId就可以, 便于下载
    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.log",time]];

    NSError *error = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    // 如果不存在
    if(![fileManager fileExistsAtPath:filePath]) {
        [content writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
        if (error) {
            NSLog(@"文件写入失败 errorInfo: %@", error.domain);
        }
    }
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    [fileHandle seekToEndOfFile];
    NSData* stringData  = [content dataUsingEncoding:NSUTF8StringEncoding];
    [fileHandle writeData:stringData]; // 追加
    [fileHandle synchronizeFile];
    [fileHandle closeFile];
}
+ (NSArray <NSString *>*)getLogDataInfo{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    return  [[NSArray alloc] initWithArray:[fileManager contentsOfDirectoryAtPath:path error:nil]];
}
+ (BOOL)removeFileWithPath:(NSString *)path{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isSuccess = [fileManager removeItemAtPath:path error:nil];
    NSLog(@"isSuccess:%d",isSuccess);
    return isSuccess;
}

#pragma mark - 初始化异常捕获系统
+ (void)initHandler {
    struct sigaction newSignalAction;
    memset(&newSignalAction, 0,sizeof(newSignalAction));
    newSignalAction.sa_handler = &signalHandler;
    sigaction(SIGABRT, &newSignalAction, NULL);
    sigaction(SIGILL, &newSignalAction, NULL);
    sigaction(SIGSEGV, &newSignalAction, NULL);
    sigaction(SIGFPE, &newSignalAction, NULL);
    sigaction(SIGBUS, &newSignalAction, NULL);
    sigaction(SIGPIPE, &newSignalAction, NULL);
    //异常时调用的函数
    NSSetUncaughtExceptionHandler(&handleExceptions);
}

void signalHandler(int sig) {
  // 打印crash信号信息
    GDLog(@"signal = %d", sig);
}

void handleExceptions(NSException *exception) {
    GDLog(@"exception = %@",exception);
    // 打印堆栈信息
    GDLog(@"callStackSymbols = %@",[exception callStackSymbols]);
}

@end
